package cn.com.dhcc.app.pub.module.authmgr.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.com.dhcc.app.core.base.BaseController;
import cn.com.dhcc.app.core.base.BaseService;
import cn.com.dhcc.app.core.base.CmCommon;
import cn.com.dhcc.app.core.base.Dao;
import cn.com.dhcc.app.core.base.log.LogType;
import cn.com.dhcc.app.core.component.db.SingleTransationCircleWithOutResult;
import cn.com.dhcc.app.core.component.db.orm.WhereCondition;
import cn.com.dhcc.app.core.component.log.Log;
import cn.com.dhcc.app.core.component.pager.Pager;
import cn.com.dhcc.app.core.component.pager.PagerData;
import cn.com.dhcc.app.core.exception.DaoException;
import cn.com.dhcc.app.core.exception.NiceException;
import cn.com.dhcc.app.core.exception.ServiceException;
import cn.com.dhcc.app.core.tag.CommonStaticCode.ENTITY_STATUS;
import cn.com.dhcc.app.core.tag.CommonStaticCode.OPERATION_TYPE;
import cn.com.dhcc.app.core.tag.CommonStaticCode.YESNO;
import cn.com.dhcc.app.core.util.CollectionUtil;
import cn.com.dhcc.app.core.util.StrUtil;
import cn.com.dhcc.app.core.util.UUIDGenerator;
import cn.com.dhcc.app.pub.core.Table.SYS_BASE_TABLE;
import cn.com.dhcc.app.pub.module.authmgr.vo.AuthRight;
import cn.com.dhcc.app.pub.module.resmgr.service.ResourceFilter;
import cn.com.dhcc.app.pub.module.resmgr.service.ResourceService;
import cn.com.dhcc.app.pub.module.resmgr.vo.LinkResource;
import cn.com.dhcc.app.pub.module.resmgr.vo.MenuResource;


/**
 * 权限对象管理服务
 * @日期：2013-6-6下午7:26:34
 * @作者：乔兵
 * @版权所有：东华软件
 * @版本：1.0
 */
@Service
public class AuthRightMgrService extends BaseService {
	//水利部上级单位默认编码
	public static final String ORG_PCODE = "000000000";
	@Autowired
	private ResourceService resourceService;
	
	public static final String CACHEED_RESOURCE_COLLECTION_KEY = "_RES_KEY_";

	Logger logger = Log.getLogger(LogType.AUTH_MGR);


	/**
	 *  根据参数获取权限分页列表
	 * @param parameter 
	 * @param offset
	 * @param pagerSize
	 * @return {List<HowTo>,total}
	 * @throws NiceException
	 */
	public PagerData<AuthRight> listRight(Pager pager, WhereCondition parameter) throws ServiceException {
		try {
			return CmCommon.getDao().getPagerModuleList("获取前线列表",AuthRight.class,parameter,pager);
		} catch (DaoException e) {
			throw new ServiceException(e);
		}
	}
	/**
	 * 根据角色获取权限列表
	 * @param roleId
	 * @return
	 * @throws ServiceException
	 */
	public List<AuthRight> listRightByRoleId(String roleId,OPERATION_TYPE type) throws ServiceException {
		try {
			String sql = null;
			Object[] args = new Object[]{};
			if(type==OPERATION_TYPE.ADD){
				sql = "select * from " +
						WSD_TABLE(SYS_BASE_TABLE.SYS_BASE_RIGHT);
						
			}else if(type==OPERATION_TYPE.GET){
				sql = "select r.* from " +
						WSD_TABLE(SYS_BASE_TABLE.SYS_BASE_RIGHT)+
						" r,"+WSD_TABLE(SYS_BASE_TABLE.SYS_BASE_REL_ROLE_RIGHT)+" rr where r.id=rr.right_id and rr.role_id=?";
				args = new Object[]{roleId};
						
			}else if(type==OPERATION_TYPE.UPDATE){
				sql = "select r.*, case when rr.right_id is not null then 'checked' else '' end checked from " +
						WSD_TABLE(SYS_BASE_TABLE.SYS_BASE_RIGHT)+
						" r left join "+WSD_TABLE(SYS_BASE_TABLE.SYS_BASE_REL_ROLE_RIGHT)+" rr on r.id=rr.right_id and rr.role_id=?";
				args = new Object[]{roleId};
						
			}
			return CmCommon.getDao().listModule("获取权限列表",sql,AuthRight.class,args);
		} catch (DaoException e) {
			throw new ServiceException(e);
		}
	}
	/**
	 * 根据参数获取角色列表
	 * @param parameter 
	 * @param offset
	 * @param pagerSize
	 * @return {List<HowTo>,total}
	 * @throws NiceException
	 */
	public List<AuthRight> listRight(WhereCondition parameter) throws ServiceException {
		try {
			return CmCommon.getDao().listModule("获取角色列表", AuthRight.class,parameter);
		} catch (DaoException e) {
			throw new ServiceException(e);
		}
	}
	
	/**
	 * 验证权限名称是否存在
	 * @param newValue
	 * @param oldValue
	 * @return
	 * @throws ServiceException
	 */
	public boolean rightNameCheck(String newValue, String oldValue) throws ServiceException {
		if(newValue==null||newValue.trim().equalsIgnoreCase(oldValue)){
			return false;
		}
		else {
			newValue = newValue.toUpperCase();
			String sql = "SELECT count(id) FROM "+WSD_TABLE(SYS_BASE_TABLE.SYS_BASE_RIGHT)+" WHERE right_name=? and status !=?";
			try {
				int num = CmCommon.getDao().queryForInt("验证角权限名称["+newValue+"]是否存在", sql, new Object[]{newValue,ENTITY_STATUS.DELETE.getCode()});
				return (num>0)?true:false;
			} catch (DaoException e) {
				throw new ServiceException(e);
			}
		}
		
	}
	/**
	 * 添加权限对象
	 * @param authRight
	 * @param menuIds
	 * @throws ServiceException
	 */
	public void addRight(final AuthRight authRight,String[] menuIds) throws ServiceException {
		if(authRight==null)return;
		final Date modified = new Date();
		String muid_c = BaseController.getUid();
		authRight.setId(UUIDGenerator.getUUID());
		authRight.setModified(modified);
		authRight.setMuid(muid_c);
		final String batchAddRelRightMenu_sql = "INSERT INTO "+WSD_TABLE(SYS_BASE_TABLE.SYS_BASE_REL_RIGHT_MENU)+" (right_id,menu_id) VALUES(?,?)";
		final List<Object[]> batchAddRelRightMenu_args = new ArrayList<Object[]>();
		
		if(StrUtil.isAllNotBlank(menuIds)){
			if(menuIds.length!=0){
				Object[] arg = null;
				for (int i = 0; i < menuIds.length; i++) {
					arg = new Object[2];
					arg[0] = authRight.getId();
					arg[1] = menuIds[i];
					batchAddRelRightMenu_args.add(arg);
				}
			}
		}
		final Dao dao = CmCommon.getDao();
		try {
			dao.doInSingleTransationCircle("添加权限", new SingleTransationCircleWithOutResult() {
				@Override
				public void actionInCircle() throws RuntimeException {
					try {
						dao.insertModule("添加权限对象", authRight);
						if(!batchAddRelRightMenu_args.isEmpty()){
						 dao.batchInsert("添加权限菜单关系", batchAddRelRightMenu_sql,batchAddRelRightMenu_args);
						}
					} catch (DaoException e) {
						throw new RuntimeException(e);
					}
				}
			});
		} catch (DaoException e) {
			throw new ServiceException(e);
		}
	}
	
	/**
	 * 修改权限
	 * @param roleInfo
	 * @param resourceStr
	 * @throws ServiceException
	 */
	public void updateRight(final AuthRight authRight,String[] menuIds) throws ServiceException{
		if(authRight==null)return;
		final Date modified = new Date();
		String muid_c = BaseController.getUid();
		authRight.setModified(modified);
		authRight.setMuid(muid_c);
		authRight.setStatus(ENTITY_STATUS.ENABLE.getCode());
		final String deleteright_menu_sql = "DELETE FROM "+WSD_TABLE(SYS_BASE_TABLE.SYS_BASE_REL_RIGHT_MENU)+" WHERE right_id=?";
		final String batchAddRelRightMenu_sql = "INSERT INTO "+WSD_TABLE(SYS_BASE_TABLE.SYS_BASE_REL_RIGHT_MENU)+" (right_id,menu_id) VALUES(?,?)";
		final List<Object[]> batchAddRelRightMenu_args = new ArrayList<Object[]>();
		
		if(StrUtil.isAllNotBlank(menuIds)){
			if(menuIds.length!=0){
				Object[] arg = null;
				for (int i = 0; i < menuIds.length; i++) {
					arg = new Object[2];
					arg[0] = authRight.getId();
					arg[1] = menuIds[i];
					batchAddRelRightMenu_args.add(arg);
				}
			}
		}
		final Dao dao = CmCommon.getDao();
		
		try {
			dao.doInSingleTransationCircle("修改权限", new SingleTransationCircleWithOutResult() {
				@Override
				public void actionInCircle() throws RuntimeException {
					try {
						dao.delete("删除权限菜单关系", deleteright_menu_sql,new Object[]{authRight.getId()});
						
						WhereCondition whereCondition = new WhereCondition();
						whereCondition.where().eq("id", authRight.getId());
						dao.updateModule("修改权限对象", authRight,whereCondition);
						
						if(!batchAddRelRightMenu_args.isEmpty()){
						 dao.batchInsert("添加权限菜单关系", batchAddRelRightMenu_sql,batchAddRelRightMenu_args);
						}
					} catch (DaoException e) {
						throw new RuntimeException(e);
					}
				}
			});
		} catch (DaoException e) {
			throw new ServiceException(e);
		}
		
		
		}
	
	/**
	 * 获取权限对应的菜单数字符串
	 * @param rightId
	 * @param forUpdate
	 * @return
	 * @throws ServiceException
	 */
	public String getMenuByRightId(String rightId,final OPERATION_TYPE operationType) throws ServiceException {
		
		if((OPERATION_TYPE.UPDATE==operationType||OPERATION_TYPE.GET==operationType)&&StrUtil.isBlank(rightId))return "";
		
		final Set<String> menuList = new HashSet<String>();
		
		String preWhereSql = 
				" SELECT menu_id FROM "+WSD_TABLE(SYS_BASE_TABLE.SYS_BASE_REL_RIGHT_MENU)+" rm where 1=1";
		/*String preWhereSql_for_link = 
				" SELECT ml.link_id FROM "+WSD_TABLE(SYS_BASE_TABLE.SYS_BASE_REL_RIGHT_MENU)+" rm, "+
		          WSD_TABLE(SYS_BASE_TABLE.SYS_BASE_REL_MENU_LINK)+" ml "+
				 "where rm.menu_id=ml.menu_id";*/
		WhereCondition parameter = new WhereCondition();
		parameter.andEq("rm.right_id",rightId);
		try {
			List<Map<String, Object>> menus = CmCommon.getDao().listMap("获取角色菜单权限", preWhereSql, parameter,new Object[]{});
			 if(CollectionUtil.hasElement(menus)){
				 for (Iterator<Map<String, Object>> iterator = menus.iterator(); iterator
						.hasNext();) {
					Map<String, Object> map = (Map<String, Object>) iterator
							.next();
					menuList.add((String)map.get("menu_id"));
				}
			 }
			 /*List<Map<String, Object>> links = CmCommon.getDao().listMap("获取角色链接权限", preWhereSql_for_link, parameter,new Object[]{});
			 final Set<String> linkList = new HashSet<String>();
			 if(CollectionUtil.hasElement(links)){
				 for (Iterator<Map<String, Object>> iterator = links.iterator(); iterator
						.hasNext();) {
					Map<String, Object> map = (Map<String, Object>) iterator
							.next();
					linkList.add((String)map.get("link_id"));
				}
			 }*/
		} catch (DaoException e) {
			throw new ServiceException(e);
		}
		ResourceFilter filter = new ResourceFilter() {
			@Override
			public boolean selectCurrentNode(MenuResource resource) {
				return (operationType!=OPERATION_TYPE.ADD&&menuList.contains(resource.getId()));
			}
			@Override
			public boolean removeCurrentNode(MenuResource resource) {
				//查询的时候不显示没有配置的菜单
				return (!menuList.contains(resource.getId())&&(OPERATION_TYPE.GET==operationType))||YESNO.YES.getStatus().equalsIgnoreCase(resource.getHidden());
			}
			@Override
			public boolean openCurrentNode(MenuResource resource) {
				return false;//rslist.contains(resource.getId());
			}
			@Override
			public boolean nocheck(MenuResource resource) {
				return false;
			}
			@Override
			public boolean selectCurrentNode(LinkResource linkResource) {
				return false;
			}
			@Override
			public boolean removeCurrentNode(LinkResource linkResource) {
				return true;
			}
			@Override
			public boolean nocheck(LinkResource linkResource) {
				return false;
			}
		};
		return resourceService.getResource(filter);
	}
	
	public AuthRight getRight(String rightId) throws ServiceException {
		try {
			WhereCondition condition = new WhereCondition();
			condition.where1Eq1().andEq("id", rightId);
			AuthRight authRight = getDao().getModule("根据id["+rightId+"]获取权限", AuthRight.class,condition);
			return authRight;
		} catch (DaoException e) {
			throw new ServiceException(e);
		}
	}
	public void changeRightStatus(final String rightId,final ENTITY_STATUS toRightStatus) throws ServiceException, NiceException {
		final AuthRight authRight = getRight(rightId);
		if(authRight==null){
			throw new NiceException("操作失败，权限已不存在");
		}
		if(toRightStatus.getCode().equalsIgnoreCase(authRight.getStatus())){
			throw new NiceException("操作失败，权限已为"+toRightStatus.getName()+"状态");
		}
		final Dao dao = CmCommon.getDao();
		try {
			dao.doInSingleTransationCircle("修改权限["+authRight.getRightName()+"]状态为"+toRightStatus.getName(), new SingleTransationCircleWithOutResult() {
				@Override
				public void actionInCircle() throws RuntimeException {
					try {
						if(toRightStatus==ENTITY_STATUS.REL_DELETE){
							final String deleteright_menu_sql = "DELETE FROM "+WSD_TABLE(SYS_BASE_TABLE.SYS_BASE_REL_RIGHT_MENU)+" WHERE right_id=?";
							dao.delete("删除权限菜单关系", deleteright_menu_sql,new Object[]{authRight.getId()});
						}
						WhereCondition whereCondition = new WhereCondition();
						whereCondition.where().eq("id", authRight.getId());
						if(toRightStatus==ENTITY_STATUS.DELETE){
							authRight.setStatus(ENTITY_STATUS.DELETE.getCode());
							dao.updateModule("修改权限对象", authRight,whereCondition);
						}
						if(toRightStatus==ENTITY_STATUS.REL_DELETE){
							dao.deleteModule("删除权限对象", AuthRight.class,whereCondition);
						}
					} catch (DaoException e) {
						throw new RuntimeException(e);
					}
				}
			});
		} catch (DaoException e) {
			throw new ServiceException(e);
		}
	}
}

